﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RaisingStudio.Data.Common.Expressions
{
    public class CharacterScanner : AbstractScanner
    {
        public CharacterScanner(SourceCode sourceCode)
        {
            SourceCode = sourceCode;
            _end = sourceCode.Contents.Length;
        }


        public override TokenType ReadToken(out SourceLocation tokenBegin, out SourceLocation tokenEnd)
        {
            try
            {
                if (this.SourceCode != null)
                {
                    // TODO: 
                    Space();

                    TokenType tokenType = TokenType.NONE;
                    int _begin = _current;
                    char[] Begin = Content(_begin);
                    tokenBegin.Position = _begin;
                    tokenBegin.Line = line;
                    tokenBegin.Column = column;

                    int token_length_in_chars = -1;

                    if (_current >= _end)
                    {
                        tokenType = TokenType.EOF;
                    }
                    else
                    {
                        switch (Current[0])
                        {
                            case '\'':
                                {
                                    #region character
                                    if (Begin[0] == '\'')
                                    {
                                        tokenType = TokenType.CHARACTER_LITERAL;
                                        token_length_in_chars = 2;
                                        _current++;
                                        while (_current < _end)
                                        {
                                            if (Current[0] == '\'')
                                            {
                                                if (_current < _end - 1)
                                                {
                                                    if ((Current[0] == '\'') && (Current[1] == '\''))
                                                    {
                                                        _current += 2;
                                                    }
                                                    else
                                                    {
                                                        break;
                                                    }
                                                }
                                                else
                                                {
                                                    break;
                                                }
                                            }
                                            else if (Current[0] == '\n')
                                            {
                                                break;
                                            }
                                            else
                                            {
                                                _current++;
                                            }
                                        }
                                        if (_current < _end && Current[0] != '\n')
                                        {
                                            _current++;
                                        }
                                        else
                                        {
                                            ReportError(new SourceReference(SourceCode, line, column + token_length_in_chars, line, column + token_length_in_chars), string.Format("syntax error, expected {0}", Begin));
                                        }
                                    }
                                    break;
                                    #endregion
                                }
                            default:
                                {
                                    _current++;
                                    //ReportError(new SourceReference(SourceCode, line, column, line, column), "invalid UTF-8 character");
                                    column++;
                                    return ReadToken(out tokenBegin, out tokenEnd);
                                }
                        }
                    }

                    if (token_length_in_chars < 0)
                    {
                        column += (int)(_current - _begin);
                    }
                    else
                    {
                        column += token_length_in_chars;
                    }

                    tokenEnd.Position = _current;
                    tokenEnd.Line = line;
                    tokenEnd.Column = column - 1;

                    return tokenType;
                }
                else
                {
                    tokenBegin = new SourceLocation();
                    tokenEnd = new SourceLocation();
                    return TokenType.NONE;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
            tokenBegin = new SourceLocation();
            tokenEnd = new SourceLocation();
            return TokenType.NONE;
        }
    }
}
